/*   **********************************************************************  **
 **   Copyright notice                                                       **
 **                                                                          **
 **   (c) 2009, Around(J2)ME				                                 **
 **   All rights reserved.                                                   **
 **                                                                          **
 **   This program and the accompanying materials are made available under   **
 **   the terms of the New BSD License which accompanies this    			 **
 **   distribution.											                 **
 **   A copy is found in the textfile LICENSE.txt							 **
 **                                                                          **
 **   This copyright notice MUST APPEAR in all copies of the file!           **
 **                                                                          **
 **   Main developers:                                                       **
 **     Juri Strumpflohner		http://blog.js-development.com	             **
 **		Matthias Braunhofer		http://matthias.jimdo.com                    **
 **                                                                          **
 **  **********************************************************************  */

package org.aroundme.utility;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.aroundme.model.Search;
/**
 * Class responsible for splitting up Search queries and for
 * creating the appropriate {@link Search} objects
 */
public class SearchTokenizer {
	private String[] filterSymbols = {",", ".","!"}; //TODO filter questionmarks
	//regex
	private final String REGEX_WHITESPACE = "[\\s][\\s]+";
	final String REGEX_OR_CHAIN = "[\\w]+\\sOR\\s[\\w]+[\\w]+\\sOR\\s[\\w]+[\\sOR\\s[\\w]+]*";
	final String REGEX_OR_COUPLE = "[\\w]+\\s+OR\\s+[\\w]+";
	
	private String searchString;
	private Search searchObject;
	
	public SearchTokenizer(){
	}
	
	public Search createSearchObject(String searchQuery){
		initialize(searchQuery);
		
		return searchObject;
	}
	
	/**
	 * Initialize the tokenizer
	 */
	private void initialize(String searchString){
		this.searchString = searchString;
		this.searchObject = new Search("all");
		searchString = searchString.trim();
		cleanSearchQuery();
		filterOR_CHAINKeywords();
		filterORKeywords();	
		filterANDKeywords(); //HAS to be the last step
	}
	
	/**
	 * Filters out socalled OR-chains like
	 * "computer OR car OR cat OR ...".
	 * This strings are counted as chains as soon as they have more than 2 members
	 *
	 */
	private void filterOR_CHAINKeywords(){
		Pattern pattern = Pattern.compile(REGEX_OR_CHAIN);
		Matcher matcher = pattern.matcher(searchString);
		
		while(matcher.find()){
			String found = searchString.substring(matcher.start(), matcher.end());
			//split and store 1st of the couple x OR y
			String[] tmp = found.split(" OR ");
			for (String string : tmp) {
				searchObject.addKeywordOR(string);
			}
			//cut search query
			searchString = searchString.substring(0, matcher.start()) + searchString.substring(matcher.end(), searchString.length());
			searchString = searchString.trim();	
		}
	}
	
	/**
	 * Filters out an OR-couple like
	 * "computer OR car"
	 *
	 */
	private void filterORKeywords() {
		Pattern pattern = Pattern.compile(REGEX_OR_COUPLE);
		Matcher matcher = pattern.matcher(searchString);
		
		while(matcher.find()){
			String found = searchString.substring(matcher.start(), matcher.end());
			//split and store 1st of the couple x OR y
			String[] tmp = found.split(" OR ");
			for (String string : tmp) {
				searchObject.addKeywordOR(string);
			}
			//cut search query
			searchString = searchString.substring(0, matcher.start()) + searchString.substring(matcher.end(), searchString.length());
			searchString = searchString.trim();	
		}
	}
	
	/**
	 * eliminates all remaining "AND"'s from the search query
	 * and filters out the single words by splitting the string
	 *
	 */
	private void filterANDKeywords(){
		searchString = searchString.replaceAll(" AND ", " ");
		
		//tokenize
		String[] tmp = searchString.split(" ");
		for(int i=0; i<tmp.length; i++){
			searchObject.addKeywordAND(tmp[i]);
		}
	}
	
	/**
	 * Cleans the search-string
	 */
	private void cleanSearchQuery(){
		searchString = searchString.replaceAll(REGEX_WHITESPACE, " ");
		//replace "or" to "OR" and "and" to "AND"
		searchString = searchString.replaceAll(" or ", " OR ");
		searchString = searchString.replaceAll(" and ", " AND ");
		//TODO query filtering
//		for (String s : filterSymbols) {
//			searchString = searchString.replaceAll(s, "");
//		}
	}
	
	
}